﻿using FlowSequencer.Core.FlowElements;
using FlowSequencer.Core.Sequencer;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FlowSequencer.Core.Tests
{
    [TestClass]
    public class CyclicExecutiveSchedulingTest
    {
        [TestMethod]
        public void CanGetOptiamlFlow()
        {
            ISequencer sequencer = new CyclicExecutiveScheduling();
            var periodList = new Line()
            {
                Tasks = new List<Task>() 
                {
                    new Task() { Name = "Z1", Index = 0, Cycles = 20 },
                    new Task() { Name = "Z2", Index = 1, Cycles = 40 },
                    new Task() { Name = "Z3", Index = 2, Cycles = 80 },
                    new Task() { Name = "Z4", Index = 3, Cycles = 80 },
                    new Task() { Name = "Z5", Index = 4, Cycles = 80 },
                    new Task() { Name = "Z6", Index = 5, Cycles = 80 },
                }
            };
            var processingTimeList = new Line()
            {
                Tasks = new List<Task>() 
                {
                    new Task() { Name = "Z1", Index = 0, Cycles = 4 },
                    new Task() { Name = "Z2", Index = 1, Cycles = 10 },
                    new Task() { Name = "Z3", Index = 2, Cycles = 6 },
                    new Task() { Name = "Z4", Index = 3, Cycles = 16 },
                    new Task() { Name = "Z5", Index = 4, Cycles = 6 },
                    new Task() { Name = "Z6", Index = 5, Cycles = 12 },
                }
            };
            var realativeDeadlineList = new Line()
            {
                Tasks = new List<Task>() 
                {
                    new Task() { Name = "Z1", Index = 0, Cycles = 20 },
                    new Task() { Name = "Z2", Index = 1, Cycles = 40 },
                    new Task() { Name = "Z3", Index = 2, Cycles = 80 },
                    new Task() { Name = "Z4", Index = 3, Cycles = 80 },
                    new Task() { Name = "Z5", Index = 4, Cycles = 80 },
                    new Task() { Name = "Z6", Index = 5, Cycles = 80 },
                }
            };
            sequencer.InsertLine(periodList);
            sequencer.InsertLine(processingTimeList);
            sequencer.InsertLine(realativeDeadlineList);
            sequencer.ComputeFlow();
            var flow = sequencer.GetOptimizedFlow();

            Assert.AreEqual("Z1", flow.Lines[0].Tasks[0].Name);
            Assert.AreEqual(4, flow.Lines[0].Tasks[0].Cycles);

            Assert.AreEqual("Z2", flow.Lines[0].Tasks[1].Name);
            Assert.AreEqual(10, flow.Lines[0].Tasks[1].Cycles);

            Assert.AreEqual("Z3", flow.Lines[0].Tasks[2].Name);
            Assert.AreEqual(6, flow.Lines[0].Tasks[2].Cycles);

            Assert.AreEqual("Z1", flow.Lines[0].Tasks[3].Name);
            Assert.AreEqual(4, flow.Lines[0].Tasks[3].Cycles);

            Assert.AreEqual("Z4", flow.Lines[0].Tasks[4].Name);
            Assert.AreEqual(16, flow.Lines[0].Tasks[4].Cycles);

            Assert.AreEqual("Z1", flow.Lines[0].Tasks[5].Name);
            Assert.AreEqual(4, flow.Lines[0].Tasks[5].Cycles);

            Assert.AreEqual("Z2", flow.Lines[0].Tasks[6].Name);
            Assert.AreEqual(10, flow.Lines[0].Tasks[6].Cycles);

            Assert.AreEqual("Z5", flow.Lines[0].Tasks[7].Name);
            Assert.AreEqual(6, flow.Lines[0].Tasks[7].Cycles);

            Assert.AreEqual("Z1", flow.Lines[0].Tasks[8].Name);
            Assert.AreEqual(4, flow.Lines[0].Tasks[8].Cycles);

            Assert.AreEqual("Z6", flow.Lines[0].Tasks[9].Name);
            Assert.AreEqual(12, flow.Lines[0].Tasks[9].Cycles);
        }
    }
}
